#pragma once

#include <functional>
#include <iostream>
#include "Socket.hpp"

class Connection;
class Reactor;
using func_t = std::function<void(Connection*)>;

class Connection
{
public:
    Connection(int fd, uint32_t events, Reactor *R, func_t recver, func_t sender, func_t excepter)
    : _sockfd(fd), _events(events), _R(R), _recver(recver), _sender(sender), _excepter(excepter)
    {}
    ~Connection()
    {}
    
    int Sockfd()
    {
        return _sockfd;
    }
    uint32_t Events()
    {
        return _events;
    }

    void SetInBuffer(const std::string &msg)
    {
        _inbuffer += msg;
    }
    void SetOutBuffer(const std::string &msg)
    {
        _outbuffer += msg;
    }
    std::string& GetInbuffer()
    {
        return _inbuffer;
    }
    std::string& GetOutbuffer()
    {
        return _outbuffer;
    }

private:
    int _sockfd;
    uint32_t _events;
    std::string _inbuffer;
    std::string _outbuffer;
public:
    Reactor *_R;
    func_t _recver;
    func_t _sender;
    func_t _excepter;
};

class ConntionFactory
{
public:
    static Connection* BuildListenConnection(int port, Reactor *R, func_t recver, func_t sender, func_t excepter)
    {
        Socket *sock = new TcpSocket();
        sock->BulidListenSocket(port);
        uint32_t events = EPOLLIN | EPOLLET;
        Connection *conn = new Connection(sock->GetSocket(), events, R, recver, sender, excepter);
        delete sock;
        return conn;
    }
    static Connection* BuildNormalConnection(int fd, Reactor *R, func_t recver, func_t sender, func_t excepter)
    {
        uint32_t events = EPOLLIN | EPOLLET;
        Connection *conn = new Connection(fd, events, R, recver, sender, excepter);
        return conn;
    }
};